package org.gongliang.jsmile.common.aop;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang3.exception.ExceptionUtils;
import org.apache.shiro.authz.UnauthorizedException;
import org.gongliang.jsmile.authc.sys.entity.SysLog;
import org.gongliang.jsmile.common.base.JSmileResult;
import org.gongliang.jsmile.common.enums.KException;
import org.gongliang.jsmile.common.enums.SF;
import org.gongliang.jsmile.common.exception.JSmileException;
import org.gongliang.jsmile.common.kit.BeanKit;
import org.gongliang.jsmile.common.kit.web.WebKit;
import org.gongliang.jsmile.config.log.info.KLog;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerExceptionResolver;
import org.springframework.web.servlet.ModelAndView;

import com.alibaba.fastjson.support.spring.FastJsonJsonView;

/**
 * 
 * @Description 全局异常处理
 * @author 龚亮
 * @date 2017年3月30日 下午3:34:16
 */
public class KExceptionHandler implements HandlerExceptionResolver {

	private static final Logger logger = LoggerFactory.getLogger(KExceptionHandler.class);

	@Override
	public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler,
			Exception exception) {
		logger.error("异常信息:" + ExceptionUtils.getStackTrace(exception));
		Class<? extends Exception> cls = exception.getClass();
		FastJsonJsonView jsonView = new FastJsonJsonView();
		ModelAndView mv = new ModelAndView();
		JSmileResult result = JSmileResult.error();
		if (cls.isAssignableFrom(JSmileException.class)) {
			// 逻辑异常
			Integer resCode = ((JSmileException) exception).getErrCode();
			String resMsg = ((JSmileException) exception).getErrMsg();
			result.setResCode(resCode);
			result.setResMsg(resMsg);
		} else if (cls.isAssignableFrom(UnauthorizedException.class)) {
			result=JSmileResult.error(KException.NOT_PERMISSION);
		} else {
			// 其它异常
			result=JSmileResult.error(KException.REQUEST_ERROR);
		}
		if (handler instanceof HandlerMethod) {
			HandlerMethod method = (HandlerMethod) handler;
			if (method.hasMethodAnnotation(ResponseBody.class)
					|| method.getBeanType().isAnnotationPresent(RestController.class)
					|| WebKit.isAjaxRequest(request)) {
				jsonView.setAttributesMap(BeanKit.beanToMap(result));
				mv.setView(jsonView);
			} else {
				if (cls.isAssignableFrom(UnauthorizedException.class)) {
					mv.setViewName("redirect:/html/unauthc.html");
				} else {
					mv.setViewName("redirect:/html/500.html");
				}
			}
			if (method.hasMethodAnnotation(KLog.class)) {
				SysLog log = new SysLog();
				log.setIsOk(SF.F.getValue());
				log.setException(ExceptionUtils.getStackTrace(exception));
				try {
					LogKit.handle(log, method.getMethodAnnotation(KLog.class));
				} catch (Exception e) {
					logger.error("日志记录发生异常:" + ExceptionUtils.getStackTrace(exception));
				}
			}
		}
		return mv;
	}

}
